import { AnalyzerConfigSchemas } from './schemas/AnalyzerConfigSchemas';

/**
 * Configuration Manager
 * Manages analyzer configurations, profiles, and persistence.
 */
class ConfigurationManager {
    constructor() {
        this.activeConfigs = new Map(); // In-memory config cache
        this.schemas = AnalyzerConfigSchemas;
        this.initialized = false;
    }

    /**
     * Initialize the manager (load defaults)
     */
    async init() {
        if (this.initialized) return;
        try {
            await this.loadFromStorage();
            this.initialized = true;
            console.log('[ConfigurationManager] Initialized');
        } catch (error) {
            console.error('[ConfigurationManager] Init failed:', error);
        }
    }

    /**
     * Get configuration for an analyzer
     * Merges default values with user overrides
     * @param {string} analyzerId 
     * @returns {Object} Config object
     */
    getConfig(analyzerId) {
        const userConfig = this.activeConfigs.get(analyzerId) || {};
        const defaultConfig = this.getDefaultConfig(analyzerId);
        return { ...defaultConfig, ...userConfig };
    }

    /**
     * Get default configuration from schema
     * @param {string} analyzerId 
     * @returns {Object} Default config
     */
    getDefaultConfig(analyzerId) {
        const schema = this.schemas[analyzerId];
        if (!schema) {
            console.warn(`[ConfigurationManager] Unknown analyzer: ${analyzerId}`);
            return {};
        }

        const config = {};
        schema.parameters.forEach(p => {
            config[p.id] = p.defaultValue;
        });
        return config;
    }

    /**
     * Save configuration for an analyzer
     * @param {string} analyzerId 
     * @param {Object} config 
     */
    async saveConfig(analyzerId, config) {
        // Validate first
        const validation = this.validateConfig(analyzerId, config);
        if (!validation.valid) {
            throw new Error(`Configuration validation failed: ${validation.errors.join(', ')}`);
        }

        this.activeConfigs.set(analyzerId, config);

        // Persist to "default_configs" profile for now
        // In a real app, we might let users choose which profile to save to
        await this.persistToProfile('default_configs', this.activeConfigs);
    }

    /**
     * Persist current state to a profile in DB
     */
    async persistToProfile(profileName, configMap) {
        if (!window.electronAPI) return;

        const configs = Object.fromEntries(configMap);
        try {
            await window.electronAPI.config.saveProfile({
                name: profileName,
                configs: configs,
                description: 'Auto-saved default configuration'
            });
        } catch (error) {
            console.error('[ConfigurationManager] Failed to persist profile:', error);
            throw error;
        }
    }

    /**
     * Load configurations from storage (DB)
     */
    async loadFromStorage() {
        if (!window.electronAPI) return;

        try {
            const profiles = await window.electronAPI.config.getProfiles();
            const defaultProfile = profiles.find(p => p.name === 'default_configs');

            if (defaultProfile && defaultProfile.configs) {
                this.activeConfigs = new Map(Object.entries(defaultProfile.configs));
                console.log('[ConfigurationManager] Loaded configs from storage');
            }
        } catch (error) {
            console.error('[ConfigurationManager] Failed to load from storage:', error);
        }
    }

    /**
     * Validate configuration against schema
     */
    validateConfig(analyzerId, config) {
        const schema = this.schemas[analyzerId];
        if (!schema) return { valid: false, errors: ['Unknown analyzer'] };

        const errors = [];
        for (const param of schema.parameters) {
            const value = config[param.id];

            if (param.required && (value === undefined || value === null || value === '')) {
                errors.push(`${param.label} is required`);
                continue;
            }

            if (value !== undefined && value !== null) {
                if (param.type === 'number' || param.type === 'range') {
                    const num = Number(value);
                    if (isNaN(num)) {
                        errors.push(`${param.label} must be a number`);
                    } else {
                        if (param.min !== undefined && num < param.min) errors.push(`${param.label} too small (min ${param.min})`);
                        if (param.max !== undefined && num > param.max) errors.push(`${param.label} too large (max ${param.max})`);
                    }
                }
            }
        }

        return { valid: errors.length === 0, errors };
    }
}

// Singleton instance
export const configurationManager = new ConfigurationManager();
